package com.lucy.rabc.service.impl;

import cn.hutool.core.lang.Validator;
import com.lucy.common.constant.HttpStatus;
import com.lucy.common.domain.PageResultDTO;
import com.lucy.common.exception.BusinessException;
import com.lucy.rabc.dao.SysMenuDAO;
import com.lucy.rabc.dao.SysRoleDAO;
import com.lucy.rabc.dao.SysRoleMenuDAO;
import com.lucy.rabc.entity.SysMenu;
import com.lucy.rabc.entity.SysRole;
import com.lucy.rabc.entity.SysRoleMenu;
import com.lucy.rabc.entity.SysUser;
import com.lucy.rabc.service.SysMenuService;
import com.lucy.rabc.service.SysRoleMenuService;
import com.lucy.rabc.service.SysRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class SysRoleServiceImpl implements SysRoleService {
    @Autowired
    SysRoleDAO dao;

    @Autowired
    SysMenuService menuService;


    @Override
    public List<SysRole> getByIdBatch(List<Long> ids) {
        return dao.findByIdIn(ids);
    }

    @Override
    public PageResultDTO<SysRole> getAll(Pageable pageable, Example<SysRole> example) {
        Page<SysRole> page;

        if(Validator.isEmpty(example)){
            page = dao.findAll(pageable);
        }
        else {
            page = dao.findAll(example,pageable);
        }
        /**
         * 获取分页主体内容
         */
        List<SysRole> list = page.getContent();
        PageResultDTO<SysRole> pageResultDTO = new PageResultDTO<>();


        //封装分页请求结果
        pageResultDTO.setContent(list);
        pageResultDTO.setSize(page.getSize());
        pageResultDTO.setTotalPages(page.getTotalPages());
        pageResultDTO.setNumber(page.getNumber());
        pageResultDTO.setTotalElements(page.getTotalElements());
        return pageResultDTO;
    }

    @Override
    public List<SysRole> getExample(Example<SysRole> example) {
        return dao.findAll(example);
    }

    @Override
    public void deleteOne(Long id) {
        dao.deleteById(id);
    }

    @Override
    public Optional<SysRole> getOne(Long id) {
        return dao.findById(id);
    }

    @Override
    public SysRole saveOne(SysRole sysRole) {
        if (Validator.isNotEmpty(sysRole.getId())){
            throw new BusinessException(HttpStatus.BAD_REQUEST,"新建角色DTO不可携带ID");
        }

        return dao.save(sysRole);
    }

    @Override
    public SysRole updateOne(SysRole sysRole) {
        if (Validator.isEmpty(sysRole.getId())){
            throw new BusinessException(HttpStatus.BAD_REQUEST,"更新角色DTO必须携带ID");
        }
        return dao.save(sysRole);
    }

    @Override
    public List<SysMenu> getRoleMenus(Long roleId) {
        Optional<SysRole> roleOp = getOne(roleId);
        if (!roleOp.isPresent()){
            throw new BusinessException(HttpStatus.NOT_FOUND);
        }
        SysRole role = roleOp.get();
        List<String> permsList = role.getPermission();
        return menuService.getMenusByPermsIn(permsList);
    }

    @Override
    public List<SysMenu> getRolesMenus(List<Long> roleIds) {
        List<SysRole> roles = dao.findByIdIn(roleIds);
        Set<String> permsSet = new HashSet<>();
        for (SysRole role:roles){
            permsSet.addAll(role.getPermission());
        }
        List<String> permsList = new ArrayList<>(permsSet);
        return menuService.getMenusByPermsIn(permsList);
    }

    @Override
    public List<Long> getRoleMenuIds(Long roleId) {
        List<SysMenu> menus = getRoleMenus(roleId);
        return menus.stream().map(SysMenu::getId).collect(Collectors.toList());
    }

    @Override
    public List<Long> getRolesMenuIds(List<Long> roleIds) {
        List<SysMenu> menus = getRolesMenus(roleIds);
        return menus.stream().map(SysMenu::getId).collect(Collectors.toList());
    }
}
